using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net.Sockets;
using PokerLearner.Poker;

namespace PokerLearner.Server
{
	public partial class MainWindow : Form
	{
		#region Private Fields

		private FormLogger dialogLogger;

		#endregion

		#region Constructor

		public MainWindow()
		{
			InitializeComponent();
			PokerServer.Instance.Started += new EventHandler(Server_Started);
			PokerServer.Instance.Stopped += new EventHandler(Server_Stopped);
			PokerServer.Instance.RoundsStarted += new EventHandler(Server_RoundsStarted);
			PokerServer.Instance.RoundsPaused += new EventHandler(Server_RoundsPaused);
			PokerServer.Instance.PlayerAdded += new EventHandler<PlayerEventArgs>(Server_PlayerAdded);
			PokerServer.Instance.PlayerRemoved += new EventHandler<PlayerEventArgs>(Server_PlayerRemoved);

			dialogLogger = new FormLogger();
		}

		
		#endregion

		#region Callbacks

		private delegate void Callback();
		private delegate void PlayerCallback(Player player); 

		#endregion

		#region Player List Control		

		private void AddPlayer(Player player)
		{
			if (listViewPlayers.InvokeRequired)
			{
				this.Invoke(new PlayerCallback(AddPlayer), new object[] { player });
			}
			else
			{
				string[] columns = { player.Name, "", player.Stack.ToString() };
				ListViewItem item = new ListViewItem(columns);
				item.Tag = player;
				listViewPlayers.Items.Add(item);
			}
		}

		private void RemovePlayer(Player player)
		{
			if (listViewPlayers.InvokeRequired)
			{
				this.Invoke(new PlayerCallback(RemovePlayer), new object[] { player });
			}
			else
			{
				for(int i=0; i<listViewPlayers.Items.Count; i++)
				{
					ListViewItem item = listViewPlayers.Items[i];
					if (player.Equals(item.Tag))
					{
						listViewPlayers.Items.RemoveAt(i);
						break;
					}
				}				
			}
		}

		#endregion

		#region Menu Control

		private void EnableDisablePlay()
		{
			if (menuStripMain.InvokeRequired)
				this.Invoke(new Callback(EnableDisablePlay));
			else
			{
				if (PokerServer.Instance.Players.Count > 1 && PokerServer.Instance.Paused)
					playToolStripMenuItem.Enabled = true;
				else 
					playToolStripMenuItem.Enabled = false;
			}
		}

		private void EnableDisablePause()
		{
			if (menuStripMain.InvokeRequired)
				this.Invoke(new Callback(EnableDisablePause));
			else
			{
				if (PokerServer.Instance.Paused)
					pauseToolStripMenuItem.Enabled = false;
				else
					pauseToolStripMenuItem.Enabled = true;
			}
		}

		#endregion

		#region Log Control

		private delegate void StringCallback(string str);

		private void AddMessage(string message)
		{
			if (textBoxLog.InvokeRequired)
				this.Invoke(new StringCallback(AddMessage), new object[] { message });
			else
				textBoxLog.Text += String.Format("{0}\r\n", message);
		}

		#endregion

		#region Server Event Handlers

		void Server_Stopped(object sender, EventArgs args)
		{
			stopToolStripMenuItem.Enabled = false;
			playToolStripMenuItem.Enabled = false;
			pauseToolStripMenuItem.Enabled = false;
			startToolStripMenuItem.Enabled = true;

			AddMessage("Server stopped");
		}

		void Server_Started(object sender, EventArgs args)
		{
			stopToolStripMenuItem.Enabled = true;
			playToolStripMenuItem.Enabled = false;
			pauseToolStripMenuItem.Enabled = false;
			startToolStripMenuItem.Enabled = false;

			AddMessage("Server started");
		}

		private void Server_PlayerAdded(object sender, PlayerEventArgs args)
		{
			AddPlayer(args.Player);
			EnableDisablePlay();
			AddMessage("Player added: " + args.Player);			
		}

		private void Server_PlayerRemoved(object sender, PlayerEventArgs args)
		{
			RemovePlayer(args.Player);
			EnableDisablePlay();
			AddMessage("Player removed: " + args.Player);
		}

		void Server_RoundsPaused(object sender, EventArgs e)
		{
			AddMessage("Rounds paused");
			EnableDisablePause();
			EnableDisablePlay();
		}

		void Server_RoundsStarted(object sender, EventArgs e)
		{
			AddMessage("Rounds started");
			EnableDisablePause();
			EnableDisablePlay();
		}

		#endregion

		#region	Control	Event Handlers

		private	void startToolStripMenuItem_Click(object sender, EventArgs e)
		{
			FormStart dialog = new FormStart();
			dialog.ShowDialog();
		}

		private	void stopToolStripMenuItem_Click(object	sender,	EventArgs e)
		{
			PokerServer.Instance.Stop();
		}

		private	void aboutToolStripMenuItem_Click(object sender, EventArgs e)
		{
			// TODO: Remove	item or	do something here.
		}

		private	void MainWindow_FormClosed(object sender, FormClosedEventArgs e)
		{
			PokerServer.Instance.Stop();
		}

		private	void playToolStripMenuItem_Click(object	sender,	EventArgs e)
		{
			PokerServer.Instance.StartRounds();
		}

		private	void quitToolStripMenuItem_Click(object	sender,	EventArgs e)
		{
			PokerServer.Instance.Stop();
			dialogLogger.Close();
			this.Close();
		}

		private	void pauseToolStripMenuItem_Click(object sender, EventArgs e)
		{
			PokerServer.Instance.PauseRounds();
		}

		#endregion							

		private void exportAllToolStripMenuItem_Click(object sender, EventArgs e)
		{
			ExporterC50 exporter = new ExporterC50();
			exporter.Export("poker");
		}

		private void viewRecordsToolStripMenuItem_Click(object sender, EventArgs e)
		{
			dialogLogger.Show(this);
		}

		private void processAllToolStripMenuItem_Click(object sender, EventArgs e)
		{
			throw new NotImplementedException();
		}

		private void saveRecordsToolStripMenuItem_Click(object sender, EventArgs e)
		{
			PokerLogger.Instance.SaveRecords();
		}

		private void exportAllMatLabToolStripMenuItem_Click(object sender, EventArgs e)
		{
			ExporterMatLab exporter = new ExporterMatLab();
			exporter.Export("poker");
		}
	}
}